/**
 *
 */
// 涉及的表名
const dbName = require("../config.js");

var dao = {};
var util = {};
// 初始化
dao.init = function(obj) {
	util = obj;
}
/**
 * 查 - 根据id获取单条记录
 * @params {String} id
 * @params {Object} fieldJson 字段显示规则
 * 调用示例
 * let userCouponInfo = await vk.daoCenter.userCouponDao.findById(id);
 */
dao.findById = async (id, fieldJson) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.findById({
		dbName: dbName.userCoupon,
		id,
		fieldJson
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};
/**
 * 查 - 根据whereJson获取单条记录
 * @params {Object} whereJson 条件
 * @params {Object} fieldJson 字段显示规则
 * 调用示例
let userCouponInfo = await vk.daoCenter.userCouponDao.findByWhereJson({

});
 */
dao.findByWhereJson = async (whereJson, fieldJson) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.findByWhereJson({
		dbName: dbName.userCoupon,
		whereJson,
		fieldJson
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 增 - 添加一条记录
 * @params {Object} dataJson 添加的数据
 * 调用示例
await vk.daoCenter.userCouponDao.add({

});
 */
dao.add = async (dataJson) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.add({
		dbName: dbName.userCoupon,
		dataJson
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 增 - 添加多条记录
 * @params {Object} dataJson 添加的数据
 * 调用示例
await vk.daoCenter.userCouponDao.adds(dataArr);
 */
dao.adds = async (dataArr) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.adds({
		dbName: dbName.userCoupon,
		dataJson: dataArr
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 删 - 删除多条记录
 * @params {Object} whereJson 条件
 * 调用示例
await vk.daoCenter.userCouponDao.del({

});
 */
dao.del = async (whereJson) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.del({
		dbName: dbName.userCoupon,
		whereJson
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 删 - 据ID删除单条数据
 * @params {String} id
 * 调用示例
await vk.daoCenter.userCouponDao.deleteById(id);
 */
dao.deleteById = async (id) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.deleteById({
		dbName: dbName.userCoupon,
		id
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 改 - 批量修改
 * @params {Object} whereJson 条件
 * @params {Object} dataJson 修改的数据
 * 调用示例
await vk.daoCenter.userCouponDao.update({
	whereJson:{

	},
	dataJson:{

	}
});
 */
dao.update = async (obj = {}) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.update({
		...obj,
		dbName: dbName.userCoupon,
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 改 - 根据ID修改数据
 * @params {String} id
 * @params {Object} dataJson 修改的数据
 * 调用示例
await vk.daoCenter.userCouponDao.updateById(id, dataJson);
 */
dao.updateById = async (id, dataJson) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.updateById({
		dbName: dbName.userCoupon,
		id,
		dataJson
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 改 - 更新并返回更新后的数据（无论条件匹配到多少条记录，只会修改第一条记录，同时返回修改后的数据）
 * @params {Object} whereJson 条件
 * @params {Object} dataJson 修改的数据
 * 调用示例
await vk.daoCenter.userCouponDao.updateAndReturn({
	whereJson:{

	},
	dataJson:{

	}
});
 */
dao.updateAndReturn = async (obj = {}) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.updateAndReturn({
		...obj,
		dbName: dbName.userCoupon
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 查 - 获取记录总条数
 * @params {Object} whereJson 条件
 * 调用示例
await vk.daoCenter.userCouponDao.count(whereJson);
 */
dao.count = async (whereJson) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.count({
		dbName: dbName.userCoupon,
		whereJson
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};


/**
 * 查 - 获取数据列表
 * 调用示例
let userCouponList = await vk.daoCenter.userCouponDao.select({
	pageIndex:1,
	pageSize:20,
	getMain:false,
	whereJson:{

	},
	fieldJson:{},
	sortArr:[{ "name":"_id", "type":"desc" }],
});
 */
dao.select = async (obj = {}) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.select({
		...obj,
		dbName: dbName.userCoupon
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 查 - 获取数据列表
 * 调用示例
let userCouponList = await vk.daoCenter.userCouponDao.selects({
	pageIndex:1,
	pageSize:20,
	getMain:false,
	whereJson:{

	},
	fieldJson:{},
	sortArr:[{ "name":"_id", "type":"desc" }],
	// 副表列表
	foreignDB:[
		{
			dbName:"副表表名",
			localKey:"主表外键名",
			foreignKey:"副表外键名",
			as:"副表as字段",
			limit:1
		}
	]
});
 */
dao.selects = async (obj = {}) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.selects({
		...obj,
		dbName: dbName.userCoupon
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 查 - 获取数据列表
 * 调用示例
res = await vk.daoCenter.userCouponDao.getTableData({ data });
 */
dao.getTableData = async (obj = {}) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.getTableData({
		...obj,
		dbName: dbName.userCoupon
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 查 - 获取指定用户的可用优惠券列表
 * 调用示例
let couponList = await vk.daoCenter.userCouponDao.getCouponListByUserId({
	user_id
});
 */
dao.getCouponListByUserId = async (whereJson = {}) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.selects({
		dbName: dbName.userCoupon,
		getCount: false,
		pageIndex: 1,
		pageSize: 100,
		getMain: true,
		// 主表where条件
		whereJson,
		sortArr: [{ name: "exp_time", type: "desc" }],
		// 副表列表
		foreignDB: [{
			dbName: dbName.mallCoupon,
			localKey: "coupon_id",
			foreignKey: "_id",
			as: "couponInfo",
			limit: 1
		}]
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};


/**
 * 查 - 获取指定用户的可用优惠券信息
 * 调用示例
let couponInfo = await vk.daoCenter.userCouponDao.getCouponInfoByUserId({
	coupon_id:used_coupon_id,
	user_id
});
 */
dao.getCouponInfoByUserId = async (data = {}) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	let {
		user_id = "___",
			coupon_id = "___"
	} = data;

	res = await vk.baseDao.selects({
		dbName: dbName.userCoupon,
		pageIndex: 1,
		pageSize: 1,
		getMain: true,
		getOne: true,
		whereJson: {
			user_id,
			coupon_id
		},
		// 副表列表
		foreignDB: [{
			dbName: dbName.mallCoupon,
			localKey: "coupon_id",
			foreignKey: "_id",
			as: "couponInfo",
			limit: 1
		}]
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 将优惠券设置为已使用
 * 调用示例
let updateNum = await vk.daoCenter.userCouponDao.updateMyCouponsById(used_coupon_id, uid);
 */
dao.updateMyCouponsById = async (used_coupon_id = "___", user_id) => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	res = await vk.baseDao.update({
		dbName: dbName.userCoupon,
		whereJson: {
			_id: used_coupon_id,
			user_id,
			status: 0
		},
		dataJson: {
			status: 1,
			use_time: Date.now()
		}
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};
/**
 * 将已使用的优惠券设置为未使用（支持批量操作）
 * 调用示例
let updateNum = await vk.daoCenter.userCouponDao.resetCouponsById(used_coupon_id);
 */
dao.resetCouponsById = async (used_coupon_id = "___") => {
	let { vk, db, _ } = util;
	let res = {};
	// 数据库操作开始-----------------------------------------------------------
	let ids = [];
	if (vk.pubfn.isArray(used_coupon_id)) {
		ids = used_coupon_id;
	} else {
		ids = [used_coupon_id];
	}
	res = await vk.baseDao.update({
		dbName: dbName.userCoupon,
		whereJson: {
			_id: _.in(ids),
			status: 1
		},
		dataJson: {
			status: 0,
			use_time: _.remove()
		}
	});
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

/**
 * 增 - 给用户增加优惠券
 * 调用示例
await vk.daoCenter.userCouponDao.addCoupon({
	coupon_id: coupon_id, // 优惠券id
	user_id: user_id, // 用户id
	num: 1, // 发放数量
	source: 1, // 来源 0：自主领取 1：商家主动赠送 2：系统发放（如活动赠送等）
	remark: `商家发放`, // 发放备注
});
 */
dao.addCoupon = async (obj = {}) => {
	let { vk, _ } = util;
	let res = { code: 0, msg: "" };
	let {
		db, // 事务
		coupon_id, // 优惠券id
		user_id, // 用户id
		num = 1, // 发放数量
		source, // 来源 0：自主领取 1：商家主动赠送 2：系统发放（如活动赠送等）
		remark, // 发放备注
	} = obj;
	// 数据库操作开始-----------------------------------------------------------

	let couponInfo = await vk.daoCenter.mallCouponDao.findById(coupon_id);
	if (!couponInfo) return { code: -1, msg: "该优惠券不存在" };
	if (couponInfo.status === -1) return { code: -1, msg: "该优惠券已删除" };
	if (couponInfo.stock < num) return { code: -1, msg: "该优惠券库存不足" };
	let time = Date.now();
	let start_time, exp_time;
	let type = couponInfo.effective_time_rule.type;
	if (type === 0) {
		// 固定时间
		start_time = couponInfo.effective_time_rule.start_fixed_time;
		exp_time = couponInfo.effective_time_rule.end_fixed_time;
	} else {
		// 领取X天生效,有效期X天
		start_time = vk.pubfn.getOffsetTime(time, {
			day: couponInfo.effective_time_rule.start_dynamic_time,
			mode: "after", // after 之后 before 之前
		});
		exp_time = vk.pubfn.getOffsetTime(time, {
			day: couponInfo.effective_time_rule.end_dynamic_time,
			mode: "after", // after 之后 before 之前
		});
	}
	let ids = vk.pubfn.isArray(user_id) ? user_id : [user_id];
	let dataArr = [];
	for (let i = 0; i < ids.length; i++) {
		let id = ids[i];
		for (let j = 0; j < num; j++) {
			dataArr.push({
				status: 0,
				coupon_id,
				user_id: id,
				get_time: time,
				start_time,
				exp_time,
				source,
				remark,
			});
		}
	}
	// 先扣除优惠券库存，再增加优惠券
	let updateInfo = await vk.baseDao.updateAndReturn({
		db,
		dbName: dbName.mallCoupon,
		whereJson: {
			_id: coupon_id,
			stock: _.gte(num), // 库存必须>=领取数量
		},
		dataJson: {
			stock: _.inc(num * -1), // 扣优惠券库存
			receive_count: _.inc(num), // 增加已领取数量
		}
	});
	if (!updateInfo) return { code: -1, msg: "优惠券库存不足" };
	if (db) {
		// 如果使用了事务，则只能循环一个一个add，否则无法回滚
		res.ids = [];
		for (let i = 0; i < dataArr.length; i++) {
			let dataJson = dataArr[i];
			let id = await vk.baseDao.add({
				db,
				dbName: dbName.userCoupon,
				dataJson
			});
			res.ids.push(id);
		}
	} else {
		// 如果没有使用事务，则直接adds批量添加
		res.ids = await vk.baseDao.adds({
			dbName: dbName.userCoupon,
			dataJson: dataArr
		});
	}
	// 数据库操作结束-----------------------------------------------------------
	return res;
};

module.exports = dao;
